package net.neptech.model.sys;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.persistence.*;
import lombok.Data;
import net.neptech.utils.SnowflakeIdGenerator;
import net.neptech.utils.StringUtils;
import net.neptech.vm.constant.Constants;
import net.neptech.vm.constant.UserConstants;
import org.hibernate.annotations.GenericGenerator;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author Saya
 * @Date 2025/8/12 15:43
 * @Description TODO
 **/
@Entity
@Table(name = "sys_menu")
@TableName("sys_menu")
@Data
public class Menu implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @GenericGenerator(name = "snowflake", type = SnowflakeIdGenerator.class)
    @GeneratedValue(generator = "snowflake")
    @Column(name = "menu_id", nullable = false)
    @TableId
    public Long menuId;

    @Column(name = "menu_name", columnDefinition = "varchar(50) COMMENT '菜单名称'")
    public String menuName;

    @Column(name = "parent_id", columnDefinition = "int COMMENT '父菜单ID'")
    public Long parentId;

    @Column(name = "path", columnDefinition = "varchar(200) COMMENT '路由地址'")
    public String path;
    @Column(name = "order_num", columnDefinition = "int COMMENT '显示顺序'")
    private Integer orderNum;
    @Column(name = "is_frame", columnDefinition = "int COMMENT '是否为外链（0是 1否）'")
    private Integer isFrame;
    @Column(name = "is_cache", columnDefinition = "int COMMENT '是否缓存（0缓存 1不缓存）'")
    private Integer isCache;
    @Column(name = "remark", columnDefinition = "int COMMENT '备注'")
    private String remark;
    @Column(name = "component", columnDefinition = "varchar(255) COMMENT '组件路径'")
    public String component;

    @Column(name = "query_param", columnDefinition = "varchar(255) COMMENT '路由参数'")
    public String queryParam;

    @Column(name = "menu_type", columnDefinition = "int COMMENT '菜单类型（0目录 1菜单 2按钮）'")
    public Integer menuType;

    @Column(name = "perms", columnDefinition = "varchar(255) COMMENT '权限标识'")
    public String perms;

    @Column(name = "icon", columnDefinition = "varchar(255) COMMENT '菜单图标'")
    public String icon;

    @Column(name = "visible", columnDefinition = "int COMMENT '显示状态（0显示 1隐藏）'")
    public Integer visible;

    @Column(name = "status", columnDefinition = "int COMMENT '菜单状态（0正常 1停用）'")
    public Integer status;
    /**
     * 父菜单名称
     */
    @Transient
    @TableField(exist = false)
    private String parentName;
    /**
     * 子菜单
     */
    @Transient
    @TableField(exist = false)
    private List<Menu> children = new ArrayList<>();

    /**
     * 获取路由名称
     */
    public String getRouteName() {
        String routerName = StringUtils.capitalize(path);
        // 非外链并且是一级目录（类型为目录）
        if (isMenuFrame()) {
            routerName = StringUtils.EMPTY;
        }
        return routerName;
    }

    /**
     * 获取路由地址
     */
    public String getRouterPath() {
        String routerPath = this.path;
        // 内链打开外网方式
        if (getParentId() != 0L && isInnerLink()) {
            routerPath = innerLinkReplaceEach(routerPath);
        }
        // 非外链并且是一级目录（类型为目录）
        if (0L == getParentId() && UserConstants.TYPE_DIR.equals(getMenuType())
                && UserConstants.NO_FRAME.equals(getIsFrame())) {
            routerPath = "/" + this.path;
        }
        // 非外链并且是一级目录（类型为菜单）
        else if (isMenuFrame()) {
            routerPath = "/";
        }
        return routerPath;
    }

    /**
     * 获取组件信息
     */
    public String getComponentInfo() {
        String component = UserConstants.LAYOUT;
        if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
            component = this.component;
        } else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
            component = UserConstants.INNER_LINK;
        } else if (StringUtils.isEmpty(this.component) && isParentView()) {
            component = UserConstants.PARENT_VIEW;
        }
        return component;
    }

    /**
     * 是否为菜单内部跳转
     */
    public boolean isMenuFrame() {
        return getParentId() == 0L && UserConstants.TYPE_MENU.equals(menuType) && isFrame.equals(UserConstants.NO_FRAME);
    }

    /**
     * 是否为内链组件
     */
    public boolean isInnerLink() {
        return isFrame.equals(UserConstants.NO_FRAME) && StringUtils.ishttp(path);
    }

    /**
     * 是否为parent_view组件
     */
    public boolean isParentView() {
        return getParentId() != 0L && UserConstants.TYPE_DIR.equals(menuType);
    }

    /**
     * 内链域名特殊字符替换
     */
    public static String innerLinkReplaceEach(String path) {
        return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
                new String[]{"", "", "", "/"});
    }
}
